package com.yixing.tech.common.tcp.handler;

import com.yixing.tech.common.tcp.channel.ChannelContext;
import com.yixing.tech.common.tcp.pc.TcpMessage;
import com.yixing.tech.common.tcp.pc.TcpProducer;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.extern.slf4j.Slf4j;



import java.net.InetSocketAddress;

@Slf4j
@ChannelHandler.Sharable
public class MessageHandler extends SimpleChannelInboundHandler<String> {

    public static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    private ChannelContext channelContext;

//    private Function<TcpMessage, Void> func;

    private TcpProducer producer;

    public void setChannelContext(ChannelContext channelContext) {
        this.channelContext = channelContext;
    }

//    public void setProduceFunc(Function<TcpMessage, Void> func) {
//        this.func = func;
//    }
    public void setProducer(TcpProducer producer) {
        this.producer = producer;
    }

    public MessageHandler() {
    }

//    public MessageHandler(ChannelContext channelContext, Function<TcpMessage, Void> func) {
//        this.channelContext = channelContext;
//        this.func = func;
//    }

    public MessageHandler(ChannelContext channelContext, TcpProducer producer) {
        this.channelContext = channelContext;
        this.producer = producer;
    }

    public MessageHandler(ChannelContext channelContext) {
        this.channelContext = channelContext;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String s) throws Exception {
//        String[] strArr = s.split(" ");

        InetSocketAddress inSocket = (InetSocketAddress) ctx.channel().remoteAddress();
        String clientIP = inSocket.getAddress().getHostAddress();
        log.debug("channelRead0 recv message:[{}]", s);
//        if (strArr.length != 10 && strArr.length != 12) return;

//        if(this.func != null) {
//            TcpMessage message = new TcpMessage();
//            message.setIp(clientIP);
//            message.setPort(inSocket.getPort());
//            message.setMessage(s);
//            this.func.apply(message);
//        }

        if(producer != null) {
            TcpMessage message = new TcpMessage();
            message.setIp(clientIP);
            message.setPort(inSocket.getPort());
            message.setMessage(s.trim());
            producer.produce(message);
        }
    }


    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        try {
            log.info("channel断开连接, channelId: {}", ctx.channel().id());
        } catch (Exception ex) {
            log.info("channel断开连接");
        }
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("\n");
        log.info("成功建立连接, channelId: {}", ctx.channel().id());

        InetSocketAddress inSocket = (InetSocketAddress) ctx.channel().remoteAddress();
        String clientIP = inSocket.getAddress().getHostAddress();
        int clientPort = inSocket.getPort();
        log.info("channel远端ip: {}, 端口: {}", clientIP, clientPort);

        channelContext.addChannel(clientIP, ctx.channel());

        super.channelActive(ctx);
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        channelGroup.add(ctx.channel());
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {

        InetSocketAddress inSocket = (InetSocketAddress) ctx.channel().remoteAddress();
//        log.info("inSocket == null ? " + String.valueOf(inSocket == null));
//        String clientIP = inSocket.getAddress().getHostAddress();
//        if(!ctx.channel().isOpen()) {
//            channelContext.removeChannel(clientIP);
//
//            channelGroup.remove(ctx.channel());
//        }
        super.handlerRemoved(ctx);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();

        log.info("发生异常, 关闭channel: {}", cause.getMessage());
        ctx.channel().close();
        channelGroup.remove(ctx.channel());
    }

    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {

//        if(evt instanceof IdleStateEvent) {
//            log.info("发送心跳: {}", "AC11");
//            IdleStateEvent idleStateEvent = (IdleStateEvent) evt;
//            ctx.writeAndFlush("AC11");
//        }else {
//            super.userEventTriggered(ctx, evt);
//        }
    }

}
